from application.mapper.LikeMapper import LikeMapper
from application.model.LikeModel import LikeModel
from application.mapper.NoteMapper import NoteMapper
from application.logic.NoteLogic import get_note_by_id
from application.enumeration.ContentTypeEnum import ContentTypeEnum
from application.exception.BasicException import BasicException
from application.enumeration.StatusCodeEnum import StatusCodeEnum
from application.mapper.StatisticsMapper import StatisticsMapper
from application.model.StatisticsModel import StatisticsModel
from application.model.NoteModel import NoteModel
from typing import Optional


async def add_like(user_id: int, target_id: int, content_type: ContentTypeEnum) -> None:
    """
    添加喜欢
    :param user_id: 当前用户ID
    :param target_id: 目标ID
    :param content_type: 喜欢类型
    :return:
    """
    # 检查喜欢内容
    note_model: Optional[NoteModel] = await NoteMapper.get_data_by_id(data_id=target_id)
    if not note_model or note_model.is_disabled:
        raise BasicException(status_code=StatusCodeEnum.NOT_FOUND_ERROR, message="喜欢的内容不存在或已被封禁！")
    # 检查是否已喜欢
    if await LikeMapper.get_data_by_field(user_id=user_id, target_id=target_id):
        raise BasicException(status_code=StatusCodeEnum.ALREADY_EXIST_ERROR, message="该内容已喜欢！")
    # 添加喜欢
    if not await LikeMapper.insert(data={"user_id": user_id, "target_id": target_id, "content_type": content_type}):
        raise BasicException(status_code=StatusCodeEnum.ERROR, message="添加喜欢失败！")
    # 更新统计
    statistics_model: Optional[StatisticsModel] = await StatisticsMapper.get_data_by_field(target_id=target_id,
                                                                                           content_type=content_type)
    # 如果没有点赞记录，则新增一个
    if not statistics_model:
        await StatisticsMapper.insert(data={"target_id": target_id, "like_num": 1, "content_type": content_type})
    else:  # 有就+1
        statistics_model.like_num += 1  # 点赞数+1
        if not await StatisticsMapper.update(data=statistics_model.to_dict()):
            raise BasicException(status_code=StatusCodeEnum.ERROR, message="更新喜欢失败！")


async def delete_like_by_id(like_id: int) -> None:
    """
    根据ID删除喜欢
    :param like_id: 喜欢ID
    :return:
    """
    # 检查喜欢
    model: LikeModel = await LikeMapper.get_data_by_id(data_id=like_id)
    if not model:
        raise BasicException(status_code=StatusCodeEnum.NOT_FOUND_ERROR, message="该喜欢不存在！")
    # 删除喜欢
    if not await LikeMapper.delete(orm_model=model):
        raise BasicException(status_code=StatusCodeEnum.ERROR, message="删除喜欢失败！")


async def get_list_by_user_id(user_id: int, content_type: ContentTypeEnum, page: int, page_size: int) -> list:
    """
    根据用户ID获取喜欢列表
    :param user_id: 用户ID
    :param content_type: 喜欢内容类型
    :param page: 页码
    :param page_size: 每页数量
    :return: 喜欢列表
    """
    like_model_list: list = await LikeMapper.get_data_list(page=page, page_size=page_size, user_id=user_id,
                                                           content_type=content_type)
    result: list = []
    for like_model in like_model_list:
        # 如果是帖子，处理帖子输出
        if content_type == ContentTypeEnum.NOTE:
            result.append(await get_note_by_id(note_id=like_model.target_id))
    return result
